
import 'dart:io';

import 'package:flutter/services.dart';
import 'package:logger/logger.dart';
import 'package:path/path.dart' as path;
import 'package:sqflite/sqflite.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart';

class DbUtil {
	static final _logger = Logger(
		printer: PrettyPrinter(),
	);

	static Future<Database> connect(String dbName, [bool? isSingle, bool? isReadOnly]) async {
		String basePath = await getDatabasesPath();
		final dbPath = path.join(basePath, dbName);
		print("sqflite create basePath : $dbPath");
		return await openDatabase(dbPath, singleInstance: isSingle??true, readOnly: isReadOnly??false, version: 1,
				onCreate: (Database	db,	int version) async {
			try {
				// var isInit = await dbExisted(db);
				// if (isInit) {
				// 	print("sqflite existed: 数据库已经存在！！");
				// 	return;
				// }
				String sql = await loadSql();
				var tableSqls = sql.split(";");
				for (var sql in tableSqls) {
					var sqlStr = sql.replaceAll("\r\n", "");
					if (sqlStr.trim() == '') continue;
					await db.execute(sqlStr);
				}
				// await db.execute(sql);
			} catch(e, stackTrace) {
				_logger.e("sqflite int sql failure", error: e, stackTrace: stackTrace);
			}
		}, onOpen: (db) {
			// db.execute("PRAGMA journal_mode=WAL;");
			// db.execute("PRAGMA wal_autocheckpoint=ON;");
			print("sqflite open basePath : $dbPath");
		});
	}

	static Future<String> loadSql() async {
		String fileUrl = "assets/db/imgui-sqflite.sql";
		print("sqflite int sql : $fileUrl");
		if (Platform.isWindows || Platform.isLinux || Platform.isMacOS) {
			File file = File(fileUrl);
			var sql= await file.readAsString();
			print("sqflite int sql : $sql");
			return sql;
		} else {
			var sql = await rootBundle.loadString(fileUrl);
			print("sqflite int sql : $sql");
			return sql;
		}
	}

	static Future<bool> dbExisted(Database db) async {
		try {
			await db.rawQuery("select count(*) from im_setting");
			return true;
		} catch(e, stackTrace) {
			_logger.e("sqflite int sql failure", error: e, stackTrace: stackTrace);
		}
		return false;
	}

	static Future<Database> getDatabase() async {
		return _getDatabase(true, false);
	}

	static Future<Database> getDatabase2() async {
		return _getDatabase(false, false);
	}

	static Future<Database> getReadOnlyDatabase() async {
		return _getDatabase(false, true);
	}

	static Future<Database> _getDatabase(bool isSingle, bool isReadOnly) async {
		var startTime = DateTime.now();
		try {
			if (Platform.isWindows || Platform.isLinux || Platform.isMacOS) {
				sqfliteFfiInit();
				databaseFactory = databaseFactoryFfi;
				Database database = await DbUtil.connect("im.db", isSingle, isReadOnly);
				_logger.i("create a new database! ${database.hashCode}");
				return database;
			} else if (Platform.isAndroid) {
				databaseFactory = databaseFactory;
				Database database = await DbUtil.connect("im.db", isSingle);
				_logger.i("create a new database!");
				return database;
			}

			throw Exception("不支持这种场景");
		} finally {
			var time = DateTime.now().millisecond - startTime.millisecond;
			print("db create time: ${time}");
		}
	}

	static close(Database? database) {
		var startTime = DateTime.now();
		// database?.close();
		var time = DateTime.now().millisecond - startTime.millisecond;
		print("db close time: ${time}");
	}

	static close2(Database? database) {
		var startTime = DateTime.now();
		database?.close();
		var time = DateTime.now().millisecond - startTime.millisecond;
		print("db close time: ${time}");
	}
}